/**
 * LGPL
 * @Author jw12
 */
package org.biodas.jdas.client;

/**
 * 
 * LPGL
 *@author JWarren
 *
 */
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class NoDtdJaxbParser {

	private static final String EXTERNAL_DTD_LOADING_FEATURE =

	"http://apache.org/xml/features/nonvalidating/load-external-dtd";

	private SAXParserFactory mParserFactory = null;

	private XMLReader mParser = null;

	public NoDtdJaxbParser() {

		mParserFactory = SAXParserFactory.newInstance();

		mParserFactory.setNamespaceAware(true);

		mParserFactory.setValidating(false);

	}

	public Object parseXmlFile(File aXmlFile, String aPackage)
			throws JAXBException {

		XMLReader lReader = null;

		try {

			lReader = getXmlReader();

		} catch (Exception e) {

			JAXBException lEx = new JAXBException("Error creating SAX Parser");

			lEx.setLinkedException(e);

			throw lEx;

		}

		JAXBContext lContext = JAXBContext.newInstance(aPackage);

		Unmarshaller lUnmarshaller = lContext.createUnmarshaller();

		FileInputStream lXmlStream = null;

		try {

			try {
				lXmlStream = new FileInputStream(aXmlFile);
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			SAXSource lSource = new SAXSource(lReader, new InputSource(
					lXmlStream));

			return lUnmarshaller.unmarshal(lSource);

		} finally {

			if (lXmlStream != null) {

				try {

					lXmlStream.close();

				} catch (Exception e) {

					// ignore

				}

			}

		}

	}

	public Object parseXmlUrl(String urlString, String aPackage)
			throws JAXBException {

		XMLReader lReader = null;

		try {

			lReader = getXmlReader();

		} catch (Exception e) {

			JAXBException lEx = new JAXBException("Error creating SAX Parser");

			lEx.setLinkedException(e);

			throw lEx;

		}

		
		JAXBContext lContext = JAXBContext.newInstance(aPackage);

		Unmarshaller lUnmarshaller = lContext.createUnmarshaller();
		URL url = null;
		try {
			url = new URL(urlString);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		URLConnection uc = null;
		try {
			uc = url.openConnection();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		InputStreamReader input = null;
		SAXSource lSource = null;
		try{
		try {
			input = new InputStreamReader(uc.getInputStream());
			lSource = new SAXSource(lReader, new InputSource(input));
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return lUnmarshaller.unmarshal(lSource);
	}
		finally{
			try {
				if(input!=null)
				input.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		

	}

	private synchronized XMLReader getXmlReader()
			throws ParserConfigurationException, SAXException {

		if (mParser == null) {

			SAXParser lSaxParser = mParserFactory.newSAXParser();

			XMLReader lReader = lSaxParser.getXMLReader();

			// Implementation note: The following method call will raise an
			// exception if

			// xerxes is not the SAX Parser. You may choose instead to catch the
			// raised

			// exception and ignore it.

			lReader.setFeature(EXTERNAL_DTD_LOADING_FEATURE, false);

			mParser = lReader;

		}

		return mParser;

	}

}